package com.thinkfit.jy.utils;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.pm.PackageManager;
import android.text.TextUtils;

import androidx.core.app.ActivityCompat;

import com.blankj.utilcode.util.GsonUtils;
import com.common.lib.bean.BasicResponse;
import com.common.lib.bean.SportSectionBean;
import com.common.lib.constant.EventBusEvent;
import com.common.lib.manager.DataManager;
import com.common.lib.network.HttpMethods;
import com.common.lib.utils.LogUtil;
import com.inuker.bluetooth.library.connect.response.BleWriteResponse;
import com.inuker.bluetooth.library.utils.ByteUtils;
import com.thinkfit.jy.bean.EquipmentInfoBean;
import com.thinkfit.jy.bean.EquipmentStateBean;
import com.thinkfit.jy.bean.SportsDataBean;
import com.thinkfit.jy.ble.bluetooth.BluetoothHelper;
import com.thinkfit.jy.bluetooth.Bluetooth;
import com.thinkfit.jy.serialport.SerialPortManager;
import com.thinkfit.jy.serialport.SportStatus;
import com.thinkfit.jy.serialport.SportType;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.rxjava3.annotations.NonNull;

public class BluetoothOrder {

    private static final String TAG = "BluetoothOrder ------------->";

    private static BluetoothOrder bluetoothOrder;

    private static final int GET_EQUIPMENT_COUNT_DOWN = 400;
    private static final int GET_SPORTS_COUNT_DOWN = 660;
    private static final int OTHER_COUNT_DOWN = 300;

    private static final int LOOP_NUM = 3;

    private String bluetoothService;
    public String bluetoothMac;
    private String bluetoothCharacter;

    private String bluetoothName;

    private SerialPortManager.CurrentInfo mCurrentInfo;

    public static String mCurrentDeviceType = DeviceTypeUtils.SPINNING;

    public List<BluetoothDevice> connectedBluetooth;

    Disposable equipmentStateDisposable;
    Disposable sportsInfoDisposable;
    Disposable bluetoothOrderWriteDisposable;
    Disposable readyStartDisposable;
    Disposable treadmillStateDisposable;
    Disposable coundDisposable;

    private SportStatus mRunStatus = SportStatus.STOP;

    public static BluetoothOrder getInstance() {
        if (bluetoothOrder == null) {
            bluetoothOrder = new BluetoothOrder();
        }
        return bluetoothOrder;
    }

    public void setBluetoothService(String service) {
        bluetoothService = service;
    }

    public void setBluetoothMac(String mac) {
        bluetoothMac = mac;
    }

    public void setBluetoothName(String name) {
        bluetoothName = name;
    }

    public String getBluetoothName() {
        return bluetoothName;
    }

    public void setBluetoothCharacter(String character) {
        bluetoothCharacter = character;
    }

    //获取设备品牌 ID 和机型 ID
    public static final byte[] EQUIPMENT_GET_BRAND_ID_TYPE_ID = new byte[]{0x02, 0x50, 0x00, 0x50, 0x03};

    /********************************  车表命令     ***********************************************/
    //设备就绪指令
    public static final byte[] EQUIPMENT_READY = new byte[]{0x02, 0x44, 0x01, 0x45, 0x03};

    //设备开始或继续指令
    public static final byte[] EQUIPMENT_START_OR_CONTINUE = new byte[]{0x02, 0x44, 0x02, 0x46, 0x03};

    //设备暂停指令
    public static final byte[] EQUIPMENT_PAUSE = new byte[]{0x02, 0x44, 0x03, 0x47, 0x03};

    //设备停止指令
    public static final byte[] EQUIPMENT_STOP = new byte[]{0x02, 0x44, 0x04, 0x40, 0x03};

    //获取运动数据指令
    public static final byte[] EQUIPMENT_GET_SPORTS_INFO = new byte[]{0x02, 0x43, 0x01, 0x42, 0x03};

    //获取设备状态指令
    public static final byte[] EQUIPMENT_GET_EQUIPMENT_INFO = new byte[]{0x02, 0x42, 0x42, 0x03};

    //获取设备累计值指令
    public static final byte[] EQUIPMENT_GET_ACCUMULATIVE = new byte[]{0x02, 0x41, 0x03, 0x42, 0x03};

    //获取设备参数指令
    public static final byte[] EQUIPMENT_GET_EQUIPMENT_PARAMETER = new byte[]{0x02, 0x41, 0x02, 0x43, 0x03};

    /********************************  车表命令     ***********************************************/

    /********************************  跑步机命令    ***********************************************/
    //获取跑步机速度参数
    public static final byte[] TREADMILL_GET_SPEED = new byte[]{0x02, 0x50, 0x02, 0x52, 0x03};

    //获取跑步机坡度参数
    public static final byte[] TREADMILL_GET_SLOP = new byte[]{0x02, 0x50, 0x03, 0x53, 0x03};

    //获取跑步机累计⾥程
    public static final byte[] TREADMILL_GET_ACCUMULATIVE_MILEAGE = new byte[]{0x02, 0x50, 0x04, 0x54, 0x03};

    //获取跑步机状态
    public static final byte[] TREADMILL_GET_EQUIPMENT_INFO = new byte[]{0x02, 0x51, 0x51, 0x03};

    //设置跑步机就绪指令
    public static final byte[] TREADMILL_READY = new byte[]{0x02, 0x53, 0x01, 0x52, 0x03};

    //设置跑步机停止指令
    public static final byte[] TREADMILL_STOP = new byte[]{0x02, 0x53, 0x03, 0x50, 0x03};

    //设置跑步机开始指令
    public static final byte[] TREADMILL_START = new byte[]{0x02, 0x53, 0x09, 0x5A, 0x03};

    //设置跑步机暂停指令
    public static final byte[] TREADMILL_PAUSE = new byte[]{0x02, 0x53, 0x0A, 0x59, 0x03};


    /********************************  跑步机命令    ***********************************************/


    private SportType mSportType;  //1视频2语音3自由4实景

    private int mRid;

    /**
     * 响应信息解析
     * @param value
     */
    public void bluetoothResponse(byte[] value) {
        System.out.println(TAG + " ddddddddddddddddddddddd value : " + ByteUtils.byteToString(value));
        if (value == null || value.length <= 4) {
            return;
        }
        String instruct1 = Long.toString(value[1] & 0xff, 16);
        String instruct2 = Long.toString(value[2] & 0xff, 16);//转换会把前面的"0"给略掉，需要可以用StringBuffer拼上
        System.out.println(TAG + " ddddddddddddddddddddddd value[1] : " + instruct1 + "   value[2] :" + instruct2);

        if (instruct1.equals("41") && instruct2.equals("2")) {
            //设备参数
            equipmentInfo(value);

        } else if (instruct1.equals("50") && instruct2.equals("0")) {
            //获取设备品牌
            getBrandInfo(value);

        } else if (instruct1.equals("42")) {
            //获取设备状态
            getEquipmentState(value);

        } else if (instruct1.equals("43") && instruct2.equals("1")) {
            //获取运动数据
            getSportsData(value);
        } else if (instruct1.equals("44") && instruct2.equals("1")) {
            //准备就绪
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面准备就绪状态  ");
            if (mRunStatus == SportStatus.START) {
                return;
            }
            mRunStatus = SportStatus.START;
            int countdown = formatHexInt(Long.toString(value[3] & 0xff, 16));
            System.out.println(TAG + "ddddddddddddddddddddddd  countdown : " + countdown);
            if (countdown > 0) {
                HashMap<String, Object> map = new HashMap<>();
                map.put(EventBusEvent.START_RUN, countdown);
                EventBus.getDefault().post(map);
            } else {
                System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaa    1111");
                bluetoothOrderWrite(EQUIPMENT_START_OR_CONTINUE);
            }
        } else if (instruct1.equals("44") && instruct2.equals("2")) {
            //设备开始或继续
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新开始状态  " + (mRunStatus == SportStatus.RUNNING));
            if (mRunStatus == SportStatus.RUNNING) {
                return;
            }
            mRunStatus = SportStatus.RUNNING;

            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新开始状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.RUNNING, 0);
            EventBus.getDefault().post(map);

            getEquipmentState();//获取设备状态

        } else if (instruct1.equals("44") && instruct2.equals("3")) {
            //设备暂停
            if (mRunStatus == SportStatus.PAUSE) {
                return;
            }
            mRunStatus = SportStatus.PAUSE;
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新暂停状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.PAUSE_RUN, 0);
            EventBus.getDefault().post(map);
        } else if (instruct1.equals("44") && instruct2.equals("4")) {
            //设备停止
            if (mRunStatus == SportStatus.STOP) {
                return;
            }
            mRunStatus = SportStatus.STOP;
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新停止状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.STOP_RUN, 0);
            EventBus.getDefault().post(map);
        } else if (instruct1.equals("44") && instruct2.equals("5")) {
            //设置阻力和坡度

        } else if (instruct1.equals("50") && instruct2.equals("2")) {
            //获取跑步机速度参数
            setTreadmillSpeed(value);

        } else if (instruct1.equals("50") && instruct2.equals("3")) {
            //获取跑步机坡度参数
            setTreadmillSlop(value);

        } else if (instruct1.equals("50") && instruct2.equals("4")) {
            //获取跑步机累计⾥程
            setTreadmillMileage(value);

        } else if (instruct1.equals("51")) {
            //获取跑步机状态
            getTreadmillInfo(value);

        } else if (instruct1.equals("53") && instruct2.equals("1")) {
            //跑步机准备就绪
            System.out.println("ddddddddddddddddddddddd   蓝牙通知跑步机准备就绪状态  ");
            if (mRunStatus == SportStatus.START) {
                return;
            }
            mRunStatus = SportStatus.START;
            int countdown = formatHexInt(Long.toString(value[3] & 0xff, 16));
            System.out.println(TAG + " countdown : " + countdown);
            if (countdown > 0) {
                HashMap<String, Object> map = new HashMap<>();
                map.put(EventBusEvent.START_RUN, countdown);
                EventBus.getDefault().post(map);
            } else {
                HashMap<String, Object> map = new HashMap<>();
                map.put(EventBusEvent.RUNNING, 0);
                EventBus.getDefault().post(map);
                getTreadmillState();
            }

        } else if (instruct1.equals("53") && instruct2.equals("2")) {
            //跑步机设置速度和坡度指令
            treadmillSpeedAndSlope(value);


        } else if (instruct1.equals("53") && instruct2.equals("3")) {
            //跑步机停止指令
            if (mRunStatus == SportStatus.STOP) {
                return;
            }
            mRunStatus = SportStatus.STOP;
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新停止状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.STOP_RUN, 0);
            EventBus.getDefault().post(map);
        } else if (instruct1.equals("53") && instruct2.equals("9")) {
            //跑步机开始指令
            System.out.println("ddddddddddddddddddddddd   蓝牙通知跑步机刷新开始状态  " + (mRunStatus == SportStatus.RUNNING));
            if (mRunStatus == SportStatus.RUNNING) {
                return;
            }
            mRunStatus = SportStatus.RUNNING;
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新开始状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.RUNNING, 0);
            EventBus.getDefault().post(map);

        } else if (instruct1.equals("53") && instruct2.equals("A")) {
            //跑步机暂停指令
            if (mRunStatus == SportStatus.PAUSE) {
                return;
            }
            mRunStatus = SportStatus.PAUSE;
            System.out.println("ddddddddddddddddddddddd   蓝牙通知界面刷新暂停状态");
            HashMap<String, Object> map = new HashMap<>();
            map.put(EventBusEvent.PAUSE_RUN, 0);
            EventBus.getDefault().post(map);
        }
    }

    public void setSportType(SportType sportType) {
        mSportType = sportType;
    }

    public SerialPortManager.CurrentInfo getCurrentInfo() {
        if (mCurrentInfo == null) {
            return mCurrentInfo = new SerialPortManager.CurrentInfo();
        }
        return mCurrentInfo;
    }

    public void setRunStatus(SportStatus status) {
        mRunStatus = status;
    }

    public void closeCurrentInfo() {
        if (mCurrentInfo != null) {
            mCurrentInfo = null;
        }
    }

    boolean isHeartRateConnect = false;

    public void isHeartRateConnect(boolean b) {
        isHeartRateConnect = b;
    }

    /**
     * 蓝牙是否连接
     * @return
     */
    public boolean isConnect() {
        if (TextUtils.isEmpty(bluetoothMac)) {
            return false;
        }
        int connectStatus = Bluetooth.getInstance().getConnectStatus(bluetoothMac);
//        System.out.println(TAG+" isConnect :  connectStatus : "+connectStatus);
        if (connectStatus == BluetoothProfile.STATE_CONNECTED || connectStatus == BluetoothProfile.STATE_CONNECTING) {
//            System.out.println(TAG+" isConnect :  蓝牙已连接");
            if (isHeartRateConnect) {
                return false;
            }
            return true;
        }
        return false;
    }

    public List<BluetoothDevice> getBleConnectDevice(Context context) {
        ArrayList<BluetoothDevice> bleList = new ArrayList<>();
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return bleList;
        }
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); // ‌:ml-citation{ref="3,5" data="citationList"}

        for (BluetoothDevice device : pairedDevices) {
            // 检查设备是否通过某个协议连接
            if (bluetoothAdapter.getProfileConnectionState(BluetoothProfile.A2DP)
                    == BluetoothAdapter.STATE_CONNECTED) {
                bleList.add(device);
            }
        }
        return bleList;
    }


    /**
     * 是否正在运行
     * @return
     */
    public boolean isRun() {
        return mRunStatus == SportStatus.START || mRunStatus == SportStatus.RUNNING ;
    }

    public boolean isPause() {
        return mRunStatus == SportStatus.PAUSE;
    }
    public boolean isStop() {
        return mRunStatus == SportStatus.STOP;
    }


    public void startPlay(){
        if(MotionDataUtils.getInstance().isPause()){
            System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaa    2222");
            bluetoothOrderWrite(EQUIPMENT_START_OR_CONTINUE);
        }else {
            bluetoothOrderWrite(EQUIPMENT_READY);
        }

    }

    public void stopPlay(){
        if(MotionDataUtils.getInstance().isRun()){
            bluetoothOrderWrite(EQUIPMENT_STOP);
        }
    }


    /**
     * 开始跑步机
     */
    public void startTreadmill(){
        System.out.println("ddddddddddddddddddddddd   蓝牙通知跑步机开始");
        if(MotionDataUtils.getInstance().isPause()){
            bluetoothOrderWrite(TREADMILL_START);
        }else {
            bluetoothOrderWrite(TREADMILL_READY);
        }

    }

    /**
     * 停止跑步机
     */
    public void stopTreadmill(){
        System.out.println("ddddddddddddddddddddddd   蓝牙通知跑步机停止  :"+isRun());
        if(MotionDataUtils.getInstance().isRun()){
            bluetoothOrderWrite(TREADMILL_STOP);
        }
    }

    /**
     * 暂停跑步机
     */
    public void pauseTreadmill(){
        if(MotionDataUtils.getInstance().isRun()){
            bluetoothOrderWrite(TREADMILL_PAUSE);
        }
    }

    /**
     * 获取跑步机速度
     */
    public void getTreadmillSpeed(){
        bluetoothOrderWrite(TREADMILL_GET_SPEED);
    }

    public void setTreadmillSpeed(byte[] value){
        int speedMax = formatHexInt(Long.toString(value[3] & 0xff, 16));//速度
        int speedMin = formatHexInt(Long.toString(value[4] & 0xff, 16));//速度

        EquipmentInfoBean equipmentInfoBean = EquipmentInfoUtils.getInstance().getEquipmentInfoBean();
        equipmentInfoBean.setResistance(speedMax);

        System.out.println(TAG +" ddddddddddddddddddddddd  TreadmillSpeed  "+speedMax);

        EquipmentInfoUtils.getInstance().saveEquipmentInfoBean(GsonUtils.toJson(equipmentInfoBean));

    }

    /**
     * 获取跑步机坡度
     */
    public void getTreadmillSlop(){
        bluetoothOrderWrite(TREADMILL_GET_SLOP);
    }
    public void setTreadmillSlop(byte[] value){
        int slopMax = formatHexInt(Long.toString(value[3] & 0xff, 16));//坡度
        int slopMin = formatHexInt(Long.toString(value[4] & 0xff, 16));//坡度
        int config = formatHexInt(Long.toString(value[5] & 0xff, 16));//配置
        int unitType = 0;
        int isPause = 0;
        if(config == 0){
            unitType = 0;
            isPause = 0;
        }else if(config == 1){
            unitType = 1;
            isPause = 0;
        }else if(config == 2){
            unitType = 0;
            isPause = 1;
        }else if(config == 3){
            unitType = 1;
            isPause = 1;
        }

        EquipmentInfoBean equipmentInfoBean = EquipmentInfoUtils.getInstance().getEquipmentInfoBean();
        equipmentInfoBean.setSlope(slopMax);
        equipmentInfoBean.setIsPause(isPause);
        equipmentInfoBean.setUnitType(unitType);
        DataManager.Companion.getInstance().saveUnit((unitType==1));


        System.out.println(TAG +" ddddddddddddddddddddddd  TreadmillSlop "+ equipmentInfoBean.toString());

        EquipmentInfoUtils.getInstance().saveEquipmentInfoBean(GsonUtils.toJson(equipmentInfoBean));
    }

    /**
     * 获取跑步机累计里程
     */
    public void getTreadmillMileage(){
        bluetoothOrderWrite(TREADMILL_GET_ACCUMULATIVE_MILEAGE);
    }

    public void setTreadmillMileage(byte[] value){
        int mileage1 = formatHexInt(Long.toString(value[3] & 0xff, 16));//里程
        int mileage2 = formatHexInt(Long.toString(value[4] & 0xff, 16));//里程
        int mileage3 = formatHexInt(Long.toString(value[5] & 0xff, 16));//里程
        int mileage4 = formatHexInt(Long.toString(value[6] & 0xff, 16));//里程
    }

    /**
     * 设置跑步机速度和坡度
     * @param speed
     * @param slope
     * @return
     */
    public void setTreadmillSpeedAndSlope(int speed,int slope){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("02");
        stringBuffer.append("53");
        stringBuffer.append("02");
        stringBuffer.append(integerToHexString(speed));
        stringBuffer.append(integerToHexString(slope));
        stringBuffer.append("00");
        stringBuffer.append("03");
        byte[] bytes = hexToByteArray(stringBuffer.toString());
        byte b = SerialPortManager.getInstance().UartFCS(bytes, bytes.length-2);
        System.out.println(TAG+" ddddddddddddddddddddddd  "+Long.toString(b & 0xff, 16));
        bytes[5] = b;

        bluetoothOrderWrite(bytes);
    }

    public void  treadmillSpeedAndSlope(byte[] value){
        int speed = formatHexInt(Long.toString(value[3] & 0xff, 16));//速度
        int slop = formatHexInt(Long.toString(value[4] & 0xff, 16));//坡度
        getCurrentInfo().speed = speed;
        getCurrentInfo().slop = slop;
    }

    /**
     * 循环获取跑步机状态
     */
    public void getTreadmillState(){
        closeTreadmillStateDisposable();
        Observable.interval(GET_EQUIPMENT_COUNT_DOWN, TimeUnit.MILLISECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        treadmillStateDisposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        Bluetooth.getInstance().write(bluetoothMac, UUID.fromString(bluetoothService)
                                , UUID.fromString(bluetoothCharacter), TREADMILL_GET_EQUIPMENT_INFO, new BleWriteResponse() {
                                    @Override
                                    public void onResponse(int code) {
                                        LogUtil.LogE(TAG+"  ddddddddddddddddddddddd  getTreadmillState   Write : "+code);

                                    }
                                });
                    }

                    @Override
                    public void onError(Throwable e) {
                        closeTreadmillStateDisposable();
                    }

                    @Override
                    public void onComplete() {
                        closeTreadmillStateDisposable();
                    }
                });
    }
    public void getTreadmillInfo(byte[] value){
        HashMap<String, Object> map = new HashMap<>();
        if(value.length <= 5){
            return;
        }
        byte b = SerialPortManager.getInstance().UartFCS(value, value.length-2);
        if(b != value[value.length-2]){
            System.out.println("ddddddddddddddddddddddd    丢包数据 : " + ByteUtils.byteToString(value));
            return;
        }
        int stats = formatHexInt(Long.toString(value[2] & 0xff, 16));//状态
        System.out.println("ddddddddddddddddddddddd    stats  : "+stats+"       "+ mRunStatus);
        if(stats == 4){
            SportsStatusBarViewUtils.getInstance().setEnabled(false);
        }else {
            SportsStatusBarViewUtils.getInstance().setEnabled(true);
        }
        if(stats == 6){
            int type = formatHexInt(Long.toString(value[3] & 0xff, 16));
            if(type == 2){
                System.out.println("ddddddddddddddddddddddd    stats    跑步机睡眠中");
//                ToastUtils.showShort("跑步机休眠中");
            }else if(type == 1){
                System.out.println("ddddddddddddddddddddddd    stats    跑步机安全锁中");
//                ToastUtils.showShort("跑步机安全锁中");
            }
            return;
        }else if(stats == 0){
            System.out.println("ddddddddddddddddddddddd    stats    跑步机停止" + mRunStatus);
            if(mRunStatus == SportStatus.STOP){
                return;
            }
            mRunStatus = SportStatus.STOP;
            map.put(EventBusEvent.STOP_RUN,0);
            EventBus.getDefault().post(map);
            return;
        }else if(stats == 2){
            System.out.println("ddddddddddddddddddddddd    stats    跑步机启动中"+mRunStatus);
            if(mRunStatus == SportStatus.START){
                return;
            }
            int count = formatHexInt(Long.toString(value[3] & 0xff, 16));

            map.put(EventBusEvent.START_RUN,count);
            EventBus.getDefault().post(map);

//            int count = formatHexInt(Long.toString(value[3] & 0xff, 16));
//            map.put(EventBusEvent.START_RUN,count);
//            EventBus.getDefault().post(map);
//            System.out.println("ddddddddddddddddddddddd    跑步机启动中 11");
            return;
        }else if(stats == 10){
            System.out.println("ddddddddddddddddddddddd    stats    跑步机暂停" + mRunStatus);
            if(mRunStatus == SportStatus.PAUSE){
                return;
            }
            mRunStatus = SportStatus.PAUSE;
            SerialPortManager.getInstance().setRunStatus(SportStatus.PAUSE);
            System.out.println("ddddddddddddddddddddddd   串口通知界面刷新暂停状态");
            map.put(EventBusEvent.PAUSE_RUN,0);
            EventBus.getDefault().post(map);

        }else if(stats == 3||stats == 4){
            int speed = formatHexInt(Long.toString(value[3] & 0xff, 16));//速度
            int slop = formatHexInt(Long.toString(value[4] & 0xff, 16));//坡度
            int time1 = formatHexInt(Long.toString(value[5] & 0xff, 16));//时间
            int time2 = formatHexInt(Long.toString(value[6] & 0xff, 16));//时间
            int time = (time2*256)+time1;//时间
            int distance1 = formatHexInt(Long.toString(value[7] & 0xff, 16));//距离
            int distance2 = formatHexInt(Long.toString(value[8] & 0xff, 16));//距离
            int distance = (distance2*256)+distance1;//距离
            int heat1 = formatHexInt(Long.toString(value[9] & 0xff, 16));//热量
            int heat2 = formatHexInt(Long.toString(value[10] & 0xff, 16));//热量
            int heat = (heat2*256)+heat1;//热量
            int step1 = formatHexInt(Long.toString(value[11] & 0xff, 16));//步数
            int step2 = formatHexInt(Long.toString(value[12] & 0xff, 16));//步数
            int step = (step2*256)+step1;//步数
            int heart1 = formatHexInt(Long.toString(value[13] & 0xff, 16));//心率
            int heart2 = formatHexInt(Long.toString(value[14] & 0xff, 16));//心率
            int heart = (heart2*256)+heart1;//心率

            getCurrentInfo().speed = speed;
            getCurrentInfo().slop = slop;
            getCurrentInfo().count = step;
            getCurrentInfo().heart = heart;
            getCurrentInfo().kcal = heat;
            getCurrentInfo().distance = distance;
            getCurrentInfo().time = time;

            System.out.println(TAG+" ddddddddddddddddddddddd   TreadmillState : "+GsonUtils.toJson(getCurrentInfo()));
            map.put(EventBusEvent.EQUIPMENT_STATE,"");
            EventBus.getDefault().post(map);
        }
    }



    /**
     * 蓝牙命令写入
     * @param order
     */
    public void bluetoothOrderWrite(byte[] order){
        if(TextUtils.isEmpty(bluetoothService) || TextUtils.isEmpty(bluetoothCharacter)){
            return;
        }
        closeBluetoothOrderWrite();
        if(Arrays.equals(order,EQUIPMENT_PAUSE)||Arrays.equals(order,EQUIPMENT_STOP)){
            closeRxJavaClone();
        }
        System.out.println("ddddddddddddddddddddddd   命令 : "+ ByteUtils.byteToString(order));
        Observable.interval(OTHER_COUNT_DOWN, TimeUnit.MILLISECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        bluetoothOrderWriteDisposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        System.out.println("ddddddddddddddddddddddd   命令1111 : "+ ByteUtils.byteToString(order));
                        if(aLong >= LOOP_NUM){
                            closeBluetoothOrderWrite();

                        }
                        Bluetooth.getInstance().write(bluetoothMac, UUID.fromString(bluetoothService)
                                , UUID.fromString(bluetoothCharacter), order, new BleWriteResponse() {
                                    @Override
                                    public void onResponse(int code) {
                                        LogUtil.LogE(TAG+"  ddddddddddddddddddddddd Write : "+code);
                                        closeBluetoothOrderWrite();
                                    }
                                });
                    }

                    @Override
                    public void onError(Throwable e) {
                        closeBluetoothOrderWrite();
                    }

                    @Override
                    public void onComplete() {
                        closeBluetoothOrderWrite();
                    }
                });
    }

    /**
     * 设置阻力和坡度
     * @param nowel 阻力
     * @param slope 坡度
     */
    public void setNowelAndSlope(int nowel,int slope){
        closeBluetoothOrderWrite();
        byte[] nowelAndSlopeInstruct = getNowelAndSlopeInstruct(nowel, slope);
        Observable.interval(OTHER_COUNT_DOWN, TimeUnit.MILLISECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        bluetoothOrderWriteDisposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        if(aLong >= LOOP_NUM){
                            closeBluetoothOrderWrite();
                        }
                        Bluetooth.getInstance().write(bluetoothMac, UUID.fromString(bluetoothService)
                                , UUID.fromString(bluetoothCharacter),nowelAndSlopeInstruct , new BleWriteResponse() {
                                    @Override
                                    public void onResponse(int code) {
                                        LogUtil.LogE(TAG+"Write : "+code);
                                        closeBluetoothOrderWrite();
                                    }
                                });
                    }

                    @Override
                    public void onError(Throwable e) {
                        closeBluetoothOrderWrite();
                    }

                    @Override
                    public void onComplete() {
                        closeBluetoothOrderWrite();
                    }
                });
    }

    /**
     * 设备参数
     */
    public void blueEquipmentParameter(){
        bluetoothOrderWrite(EQUIPMENT_GET_EQUIPMENT_PARAMETER);
    }

    public byte[] getNowelAndSlopeInstruct(int nowel,int slope){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("02");
        stringBuffer.append("44");
        stringBuffer.append("05");
        stringBuffer.append(integerToHexString(nowel));
        stringBuffer.append(integerToHexString(slope));
        stringBuffer.append("00");
        stringBuffer.append("03");
        byte[] bytes = hexToByteArray(stringBuffer.toString());
        byte b = SerialPortManager.getInstance().UartFCS(bytes, bytes.length-2);
        bytes[5] = b;
        System.out.println(TAG+" ddddddddddddddddddddddd  "+Long.toString(b & 0xff, 16)+"   "+ByteUtils.byteToString(bytes));
        return bytes;
    }

    boolean isEquipmentState = true;
    /**
     * 循环获取设备状态
     */
    public void getEquipmentState(){
        if(equipmentStateDisposable != null){
            equipmentStateDisposable.dispose();
            equipmentStateDisposable = null;
        }
        Observable.interval(GET_EQUIPMENT_COUNT_DOWN, TimeUnit.MILLISECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        equipmentStateDisposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        if(isEquipmentState){
                            isEquipmentState = false;
                            Bluetooth.getInstance().write(bluetoothMac, UUID.fromString(bluetoothService)
                                    , UUID.fromString(bluetoothCharacter), EQUIPMENT_GET_EQUIPMENT_INFO, new BleWriteResponse() {
                                        @Override
                                        public void onResponse(int code) {
                                            LogUtil.LogE(TAG+"Write : "+code);
                                        }
                                    });
                        }else {
                            isEquipmentState = true;
                            Bluetooth.getInstance().write(bluetoothMac, UUID.fromString(bluetoothService)
                                    , UUID.fromString(bluetoothCharacter), EQUIPMENT_GET_SPORTS_INFO, new BleWriteResponse() {
                                        @Override
                                        public void onResponse(int code) {
                                            LogUtil.LogE(TAG+"Write : "+code);

                                        }
                                    });
                        }

                    }

                    @Override
                    public void onError(Throwable e) {
                        closeRxJavaClone();
                    }

                    @Override
                    public void onComplete() {
                        closeRxJavaClone();
                    }
                });
    }

    /**
     * 循环获取运动数据
     */
    public void getSportsInfo(){
        if(sportsInfoDisposable != null){
            sportsInfoDisposable.dispose();
            sportsInfoDisposable = null;
        }
        Observable.interval(GET_SPORTS_COUNT_DOWN, TimeUnit.MILLISECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        sportsInfoDisposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        Bluetooth.getInstance().write(bluetoothMac, UUID.fromString(bluetoothService)
                                , UUID.fromString(bluetoothCharacter), EQUIPMENT_GET_SPORTS_INFO, new BleWriteResponse() {
                                    @Override
                                    public void onResponse(int code) {
                                        LogUtil.LogE(TAG+"Write : "+code);

                                    }
                                });

                    }

                    @Override
                    public void onError(Throwable e) {
                        closeRxJavaClone();
                    }

                    @Override
                    public void onComplete() {
                        closeRxJavaClone();
                    }
                });
    }



    /**
     * 设备准备就绪
     * @param countdown
     */
    public void readyStart(int countdown){
        Observable.interval(countdown, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        readyStartDisposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        //倒计时结束后开始运动
                        closeReadyStart();
                        System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaa    3333");
                        bluetoothOrderWrite(EQUIPMENT_START_OR_CONTINUE);

                    }

                    @Override
                    public void onError(Throwable e) {
                        closeReadyStart();
                    }

                    @Override
                    public void onComplete() {
                        closeReadyStart();
                    }
                });
    }

    /**
     * 获取品牌信息
     */
    public void getBrandInfo(byte[] value){
        System.out.println(TAG+" getBrandInfo :  value : "+ByteUtils.byteToString(value)+"  value[4] : "+value[4]);
        String str = Long.toString(value[4] & 0xff, 16);
        System.out.println(TAG+" getBrandInfo :  str : "+str);
        if(DeviceTypeUtils.TREADMILL.equals(str) || DeviceTypeUtils.WALKING_TREADMILL.equals(str)){
            //跑步机
            System.out.println(TAG+" 跑步机 : ");
            mCurrentDeviceType = DeviceTypeUtils.TREADMILL;

        }else if(DeviceTypeUtils.ELLIPTICAL_MACHINE.equals(str)){
            //椭圆机
            System.out.println(TAG+" 椭圆机 : ");
            mCurrentDeviceType = DeviceTypeUtils.ELLIPTICAL_MACHINE;
        }else if(DeviceTypeUtils.SPINNING.equals(str)){
            //动感单车
            System.out.println(TAG+" 动感单车 : ");
            mCurrentDeviceType = DeviceTypeUtils.SPINNING;
        } else if (DeviceTypeUtils.ROWING_MACHINE.equals(str)) {
            //划船机
            System.out.println(TAG+" 划船机 : ");
            mCurrentDeviceType = DeviceTypeUtils.ROWING_MACHINE;
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put(EventBusEvent.REFRESH_FRAG,"");
        EventBus.getDefault().post(map);
        if (mCurrentDeviceType.equals(DeviceTypeUtils.TREADMILL)) {
            getTreadmillSpeed();
            Observable.timer(500,TimeUnit.MILLISECONDS)
                    .subscribe(new Observer<Long>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            coundDisposable = d;
                        }

                        @Override
                        public void onNext(Long aLong) {
                            if(DeviceTypeUtils.connectDeviceType() == 0){
                                getTreadmillSlop();
                            }else {
                                SerialPortManager.Cmd cmd = new SerialPortManager.Cmd();
                                cmd.bytes = TREADMILL_GET_SLOP;
                                SerialPortManager.getInstance().addCmd(cmd);
                            }

                            closeCoundDisposable();
                        }

                        @Override
                        public void onError(Throwable e) {
                            closeCoundDisposable();
                        }

                        @Override
                        public void onComplete() {
                            closeCoundDisposable();
                        }
                    });
        }else {
            if(DeviceTypeUtils.connectDeviceType() == 0){
                blueEquipmentParameter();
            }else {
                SerialPortManager.Cmd cmd = new SerialPortManager.Cmd();
                cmd.bytes = EQUIPMENT_GET_EQUIPMENT_PARAMETER;
                SerialPortManager.getInstance().addCmd(cmd);
            }

        }

    }

    /**
     * 设备参数
     * @param value
     */
    public void equipmentInfo(byte[] value){
        int resistance = formatHexInt(Long.toString(value[3] & 0xff, 16));
        int slope = formatHexInt(Long.toString(value[4] & 0xff, 16));
        int i = formatHexInt(Long.toString(value[5] & 0xff, 16));//配置
//        String s = Integer.toBinaryString(i);
//        System.out.println(TAG+" s : "+s);
        int unitType = 0;
        int isPause = 0;
        if(i == 0){
            unitType = 0;
            isPause = 0;
        }else if(i == 1){
            unitType = 1;
            isPause = 0;
        }else if(i == 2){
            unitType = 0;
            isPause = 1;
        }else if(i == 3){
            unitType = 1;
            isPause = 1;
        }
//        if(s.length() >= 8){
//            unitType = Integer.valueOf(s.charAt(0));
//            isPause = Integer.valueOf(s.charAt(1));
//        }

        EquipmentInfoBean equipmentInfoBean = new EquipmentInfoBean();
        equipmentInfoBean.setResistance(resistance);
        equipmentInfoBean.setSlope(slope);
        equipmentInfoBean.setIsPause(isPause);
        equipmentInfoBean.setUnitType(unitType);
        DataManager.Companion.getInstance().saveUnit((unitType==1));

        getCurrentInfo().resistance = resistance;
        getCurrentInfo().slop = slope;

        System.out.println(TAG +" ddddddddddddddddddddddd "+equipmentInfoBean.toString());

        SettingUtils.getInstance().saveEquipmentInfo(GsonUtils.toJson(equipmentInfoBean));

    }

    /**
     * 设备状态
     * @param value
     */
    public void getEquipmentState(byte[] value){
        if(value.length <= 8){
            return;
        }
        int stats = formatHexInt(Long.toString(value[2] & 0xff, 16));//状态
        System.out.println(TAG+"  ddddddddddddddddddddddd   stats : "+GsonUtils.toJson(getCurrentInfo()));
        if(stats == 3 || stats == 14){
            return;
        }
        int speed1 = formatHexInt(Long.toString(value[3] & 0xff, 16));//速度
        int speed2 = formatHexInt(Long.toString(value[4] & 0xff, 16));//速度
        int speed = ((speed2*256)+speed1);//速度
        int resistance = formatHexInt(Long.toString(value[5] & 0xff, 16));//阻力
        int rpm1 = formatHexInt(Long.toString(value[6] & 0xff, 16));//当前RPM
        int rpm2 = formatHexInt(Long.toString(value[7] & 0xff, 16));//当前RPM
        int rpm = (rpm2*256)+rpm1;//当前RPM
        int heartRate = formatHexInt(Long.toString(value[8] & 0xff, 16));//当前心率
        int power1 = formatHexInt(Long.toString(value[9] & 0xff, 16));//当前功率
        int power2 = formatHexInt(Long.toString(value[10] & 0xff, 16));//当前功率
        int power = ((power2*256)+power1)/10;//当前功率
        int slope = formatHexInt(Long.toString(value[11] & 0xff, 16));//当前坡度
        int reserved = formatHexInt(Long.toString(value[12] & 0xff, 16));//预留

        EquipmentStateBean equipmentStateBean = new EquipmentStateBean();
        equipmentStateBean.setSpeed(speed);
        equipmentStateBean.setResistance(resistance);
        equipmentStateBean.setRpm(rpm);
        equipmentStateBean.setHeartRate(heartRate);
        equipmentStateBean.setPower(power);
        equipmentStateBean.setSlope(slope);
        equipmentStateBean.setReserved(reserved);

        getCurrentInfo().speed = speed;
        getCurrentInfo().slop = resistance;
        getCurrentInfo().heart = heartRate;
        getCurrentInfo().rpm = rpm;
        getCurrentInfo().power = power;

        System.out.println(TAG+"  EquipmentState : "+GsonUtils.toJson(getCurrentInfo()));
        HashMap<String, Object> map = new HashMap<>();
        map.put(EventBusEvent.EQUIPMENT_STATE,getCurrentInfo());
        EventBus.getDefault().post(map);
    }

    /**
     * 运动数据
     * @param value
     */
    public void getSportsData(byte[] value){
        if(value.length <= 6){
            return;
        }
        int time1 = formatHexInt(Long.toString(value[3] & 0xff, 16));
        int time2 = formatHexInt(Long.toString(value[4] & 0xff, 16));
        int time = (time2*256)+time1;
        int distance1 = formatHexInt(Long.toString(value[5] & 0xff, 16));
        int distance2 = formatHexInt(Long.toString(value[6] & 0xff, 16));
        int distance = (distance2*256) + distance1;
        int heat1 = formatHexInt(Long.toString(value[7] & 0xff, 16));
        int heat2 = formatHexInt(Long.toString(value[8] & 0xff, 16));
        int heat = (heat2*256)+heat1;
        int num1 = formatHexInt(Long.toString(value[9] & 0xff, 16));
        int num2 = formatHexInt(Long.toString(value[10] & 0xff, 16));
        int num = (num2*256)+num1;
        SportsDataBean sportsDataBean = new SportsDataBean();
        sportsDataBean.setTime(time);
        sportsDataBean.setDistance(distance);
        sportsDataBean.setHeat(heat);
        sportsDataBean.setNum(num);

        getCurrentInfo().distance = distance;
        getCurrentInfo().kcal = heat;
        getCurrentInfo().count = num;
        getCurrentInfo().time = time;

        System.out.println(TAG+" SportsData : "+GsonUtils.toJson(getCurrentInfo()));
        System.out.println(TAG+" SportsDataBean : "+sportsDataBean.toString());

        HashMap<String, Object> map = new HashMap<>();
        map.put(EventBusEvent.SPORTS_DATA,getCurrentInfo());
        EventBus.getDefault().post(map);
    }


    public void uploadSportInfo(boolean isEnd){
        if (!DataManager.Companion.getInstance().isLogin() || getCurrentInfo().time < 10 || mSportType == null) {  //自由运动少于10秒不传
            return;
        }
        io.reactivex.rxjava3.core.Observer observer = new io.reactivex.rxjava3.core.Observer<BasicResponse<Object>>() {

            @Override
            public void onSubscribe(io.reactivex.rxjava3.disposables.@NonNull Disposable d) {

            }

            @Override
            public void onNext(BasicResponse<Object> bean) {
                if (bean.isSuccess()) {
                    mRid = bean.getRid();
                    LogUtil.LogE("mRid: " + mRid);
                }
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        };
        if (mSportType == SportType.FREE) {
            HttpMethods.Companion.getInstance().runUploadSportInfo(
                    DataManager.Companion.getInstance().getMyInfo().getUid(),
                    mRid,
                    mSportType.getValue(),
                    Utils.getNewFloat2(getCurrentInfo().distance / 1000f),
                    Utils.getNewFloat(getCurrentInfo().power * 0.1f),
                    String.valueOf(getCurrentInfo().rpm ),
                    String.valueOf(getCurrentInfo().heart),
                    Utils.getNewFloat(getCurrentInfo().power * 0.1f),
                    Utils.getNewFloat(getCurrentInfo().kcal * 0.1f),
                    getCurrentInfo().time,
                    DataManager.Companion.getInstance().getGson().toJson(new ArrayList<SportSectionBean>()), isEnd ? 1 : 0,
                    observer);
        }
    }

    public void setConnectedBluetooth(BluetoothDevice item){
        connectedBluetooth.add(item);
    }

    public List<BluetoothDevice> getConnectedBluetooth(){
        return connectedBluetooth;
    }


    public void closeRxJavaClone(){
        if(equipmentStateDisposable != null){
            equipmentStateDisposable.dispose();
            equipmentStateDisposable = null;
        }
        if(sportsInfoDisposable != null){
            sportsInfoDisposable.dispose();
            sportsInfoDisposable = null;
        }
    }

    public void closeBluetoothOrderWrite(){
        if(bluetoothOrderWriteDisposable != null){
            bluetoothOrderWriteDisposable.dispose();
            bluetoothOrderWriteDisposable = null;
        }
    }
    public void closeCoundDisposable(){
        if(coundDisposable != null){
            coundDisposable.dispose();
            coundDisposable = null;
        }
    }
    public void closeReadyStart(){
        if(readyStartDisposable != null){
            readyStartDisposable.dispose();
            readyStartDisposable = null;
        }
    }

    public void closeTreadmillStateDisposable(){
        if(treadmillStateDisposable != null){
            treadmillStateDisposable.dispose();
            treadmillStateDisposable = null;
        }
    }



    /**
     * 十六进制转十进制
     * @param str
     * @return
     */
    public int formatHexInt(String str){
        int decimalNumber = 0;
        try {
//            System.out.println(TAG+"  formatHexInt : "+str);
            decimalNumber = Integer.parseInt(str, 16);
        }catch (Exception e){
            e.printStackTrace();
        }
        return decimalNumber;
    }

    /**
     *  异或校验
     *
     * @param data 十六进制串
     * @return checkData  十六进制串
     *
     * */
    public static String checkXor(String data) {
        int checkData = 0;
        for (int i = 0; i < data.length(); i = i + 2) {
            //将十六进制字符串转成十进制
            int start = Integer.parseInt(data.substring(i, i + 2), 16);
            //进行异或运算
            checkData = start ^ checkData;
        }
        return integerToHexString(checkData);
    }

    /**
     * 将十进制整数转为十六进制数，并补位
     */
    public static String integerToHexString(int s) {
        String ss = Integer.toHexString(s);
        if (ss.length() % 2 != 0) {
            ss = "0" + ss;//0F格式
        }
        return ss.toUpperCase();
    }


    /**
     * 字符串转byte[]（没有大括号和逗号）
     * @param hexString
     * @return
     */
    public static byte[] hexToByteArray(String hexString) {
        int hexlen = hexString.length();
        byte[] result;
        if (hexlen % 2 == 1){
            //奇数
            hexlen++;
            result = new byte[(hexlen/2)];
            hexString="0"+hexString;
        }else {
            //偶数
            result = new byte[(hexlen/2)];
        }
        int j=0;
        for (int i = 0; i < hexlen; i+=2){
            result[j]= (byte) Integer.parseInt(hexString.substring(i,i+2),16);
            j++;
        }
        return result;

    }

}
